<template>
  <div class="content">
    <div class="fabricjs">
      <canvas class="fabricjsCanvas" width="500" height="500"></canvas>
    </div>
    <div class="zrender"></div>
  </div>
</template>

<script>
import { fabric } from "fabric";
import * as zrender from "zrender";

export default {
  name: "demo-event",
  data () {
    this.fabricEvent = ['selected', 'mouse:down', 'mouse:move', 'mouse:up']
    this.zrenderEvent = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseup', 'mousewheel', 'contextmenu']
    return {}
  },
  mounted() {
    this.init();
  },
  methods: {
    /**
     * 事件初始化,添加全局事件代理
     */
    fabricEventInit () {
      // 事件处理
      this.fabricEvent.forEach(eventName => {
        this.fabricjsCanvas.on(eventName, function(Event) {
          if (!Event.target) {
            return false;
          }
          let callBack = Event.target['on-' + eventName]
          callBack && callBack(Event)
        });
      })
    },
    /**
     * 绑定,添加事件
     */
    fabricAddEventListener (node, events = ['selected', 'mouse:down', 'mouse:move', 'mouse:up'], callBack) {
      // 事件由fabricEventInit统一处理
      events.forEach(eventName => {
        node['on-' + eventName] = function (Event) {
          callBack(Event)
        }
      })
    },
    /**
     * 实例初始化
     */
    fabricInit() {
      let el = this.$el.querySelector(".fabricjsCanvas");
      let fabricjsCanvas = new fabric.Canvas(el);
      this.fabricjsCanvas = fabricjsCanvas
      this.fabricEventInit()

      fabricjsCanvas.selection = false; // 禁止所有选中

      // 添加元素
      let rect = new fabric.Rect({
        // evented: true, // 是否开启事件交互, false会事件穿透
        hoverCursor: 'pointer',
        top: 100,
        left: 100,
        width: 80,
        height: 80,
        fill: "#d21e1e"
      });
      rect.hasControls = false; // 只能移动不能（编辑）操作
      rect.selectable = false; // 控件不能被选择
      rect.hasRotatingPoint = false; // 控制旋转点不可见

      this.fabricAddEventListener(rect, ['mouse:down'], function (Event) {
        console.log(Event, '-- Rect fabricAddEventListener')
      })
      fabricjsCanvas.add(rect);
      // 添加元素
      let line = new fabric.Line([80, 180, 260, 180], {
        hoverCursor: 'initial',
        fill: '#666',
        stroke: '#666',    //笔触颜色
        strokeWidth: 2,//笔触宽度
      });
      fabricjsCanvas.add(line);
      line.hasControls = false; // 只能移动不能（编辑）操作
      line.selectable = false; // 控件不能被选择
      line.hasRotatingPoint = false; // 控制旋转点不可见
      // 添加元素
      let circle = new fabric.Circle({
        hoverCursor: 'initial',
        angle: 0,
        radius: 40,
        top: 140,
        left: 140,
        fill: "#8dd02c"
      });
      circle.hasControls = false; // 只能移动不能（编辑）操作
      circle.selectable = false; // 控件不能被选择
      circle.hasRotatingPoint = false; // 控制旋转点不可见
      fabricjsCanvas.add(circle);
    },
    /**
     * 事件初始化,添加全局事件代理
     */
    zrenderEventInit () {
      this.zrenderEvent.forEach(eventName => {
        this.zR.on(eventName, function (Event) {
          if (!Event.target) {
            return false;
          }
          let callBack = Event.target['on-' + eventName]
          callBack && callBack(Event)
        })
      });
    },
    /**
     * 绑定,添加事件
     */
    zrenderAddEventListener (node, events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseup', 'mousewheel', 'contextmenu'], callBack, type = 'event') {
      // 元素绑定事件处理方法
      type === 'event' && events.forEach(eventName => {
        node.on(eventName, function (Event) {
          callBack && callBack(Event)
        })
      });

      // 事件由zrenderEventInit统一处理
      type === 'attr' && events.forEach(eventName => {
        node['on-' + eventName] = function (Event) {
          callBack(Event)
        }
      })
    },
    /**
     * 实例初始化
     */
    zrenderInit() {
      let el = this.$el.querySelector(".zrender");
      let zR = zrender.init(el);
      this.zR = zR
      this.zrenderEventInit()
      // 添加元素
      let rect = new zrender.Rect({
        cursor: 'pointer',
        shape: {
          x: 100,
          y: 100,
          width: 80,
          height: 80
        },
        style: {
          fill: "#d21e1e",
          stroke: "#d21e1e"
        }
      });
      this.zrenderAddEventListener(rect, ['click'], function (Event) {
        console.log(Event, '-- rect zrenderAddEventListener')
      })
      zR.add(rect);
      // 添加元素
      let line = new zrender.Line({
        cursor: 'initial',
        shape: {
          x1: 80,
          y1: 180,
          x2: 260,
          y2: 180,
        },
        style: {
          fill: "#666",
          stroke: "#666"
        }
      });
      zR.add(line);
      // 添加元素
      let circle = new zrender.Circle({
        cursor: 'initial',
        shape: {
          cx: 160,
          cy: 160,
          r: 40
        },
        style: {
          fill: "#8dd02c",
          stroke: "#8dd02c"
        }
      });
      zR.add(circle);
    },
    init() {
      this.fabricInit();
      this.zrenderInit();
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}

.content {
  padding: 5px;
}
.content > div {
  display: inline-block;
  width: 48%;
  height: 500px;
  border: 1px solid #eee;
}
</style>
